package edu.pe.cayetano.model.bo;

import java.util.ArrayList;

import org.apache.commons.beanutils.DynaBean;

import ws.synopsis.frmwrk.common.BResult;
import edu.pe.cayetano.dao.ModuloDAO;
import edu.pe.cayetano.dao.OperacionesComunesDAO;
import edu.pe.cayetano.dao.PerfilDAO;
import edu.pe.cayetano.dao.UsuarioDAO;
import edu.pe.cayetano.framework.BusinessException;
import edu.pe.cayetano.framework.Configuration;
import edu.pe.cayetano.model.bean.ModuloBean;
import edu.pe.cayetano.model.bean.PerfilBean;
import edu.pe.cayetano.model.bean.UsuarioBean;
import edu.pe.cayetano.seccd.constantes.ConstantesSECCD;
import edu.pe.cayetano.util.Utilitario;

public class UsuarioBO  extends BaseBO{

	private	String		schema			= Configuration.getSchemaDB();
	
	public StringBuffer estableceQuery(DynaBean dyna){
		StringBuffer 	query 		= new StringBuffer();
		String 			campo		= Utilitario.getPropertyDynaBean(dyna, "optCampo");
		String 			criterio	= Utilitario.getPropertyDynaBean(dyna, "criterio");
		String 			operacion	= Utilitario.getPropertyDynaBean(dyna, "operacion");
		String 			codigo		= Utilitario.getPropertyDynaBean(dyna, "codigo"); 

		if(ConstantesSECCD.OPERACION_BUSQUEDA.equalsIgnoreCase(operacion)&&operacion!=null){
			if(ConstantesSECCD.CRITERIO_TODOS.equalsIgnoreCase(campo)&&campo!=null){
				query.append(" SELECT A.COD_USUARIO AS COD_USUARIO,APE_PATERNO,APE_MATERNO,A.NOMBRE AS NOMBRE,USERNAME,");
				query.append(" PASSWORD,E.NOMBRE AS ESTADO,C.NOMBRE AS PERFIL");     
				query.append(" FROM "+schema+"USUARIO A ");
				query.append(" INNER JOIN "+schema+"PERFIL C");
				query.append(" ON A.COD_PERFIL=C.COD_PERFIL");
				query.append(" INNER JOIN "+schema+"ESTADO E");
				query.append(" ON E.ESTADO_ID=A.ESTADO_ID");
			}
			else{
				query.append(" SELECT A.COD_USUARIO AS COD_USUARIO,APE_PATERNO,APE_MATERNO,A.NOMBRE AS NOMBRE,USERNAME,");
				query.append(" PASSWORD,E.NOMBRE AS ESTADO,C.NOMBRE AS PERFIL");        
				query.append(" FROM "+schema+"USUARIO A ");
				query.append(" INNER JOIN "+schema+"PERFIL C");
				query.append(" ON A.COD_PERFIL=C.COD_PERFIL");
				query.append(" INNER JOIN "+schema+"ESTADO E");
				query.append(" ON E.ESTADO_ID=A.ESTADO_ID");
				query.append(" WHERE UPPER("+campo+") LIKE '%"+criterio.toUpperCase()+"%'");
			}
		}
		if(ConstantesSECCD.OPERACION_LISTADO.equalsIgnoreCase(operacion)&&operacion!=null){
				query.append(" SELECT A.COD_USUARIO AS COD_USUARIO,APE_PATERNO,APE_MATERNO,A.NOMBRE AS NOMBRE,USERNAME,");
				query.append(" PASSWORD,E.NOMBRE AS ESTADO,C.NOMBRE AS PERFIL");       
				query.append(" FROM "+schema+"USUARIO A ");
				query.append(" INNER JOIN "+schema+"PERFIL C");
				query.append(" ON A.COD_PERFIL=C.COD_PERFIL");
				query.append(" INNER JOIN "+schema+"ESTADO E");
				query.append(" ON E.ESTADO_ID=A.ESTADO_ID");
		}
		if(ConstantesSECCD.OPERACION_BUSQUEDA_ESPECIFICA.equalsIgnoreCase(operacion)){
			query.append(" SELECT A.COD_USUARIO AS COD_USUARIO,APE_PATERNO,APE_MATERNO,A.NOMBRE AS NOMBRE,USERNAME,");
			query.append(" PASSWORD,E.NOMBRE AS ESTADO,C.NOMBRE AS PERFIL");    
			query.append(" FROM "+schema+"USUARIO A ");
			query.append(" INNER JOIN "+schema+"PERFIL C");
			query.append(" ON A.COD_PERFIL=C.COD_PERFIL");
			query.append(" WHERE A.COD_USUARIO="+codigo);
		}
		System.out.println("[UsuarioBO] query en estableceQuery :"+query.toString());
		return query;
	}
	
	public BResult validaUsuario(String username,String password) throws BusinessException{
		BResult 		retSalida		= null;
		BResult 		retUsuario		= null;
		BResult 		retModulo		= null;
		BResult 		retPerfil		= null;		
		ModuloDAO		moduloDAO 	 	= null;
		PerfilDAO 		perfilDAO		= null;
		PerfilBean 		perfilTO		= null;	
		ArrayList<ModuloBean> 		listaModulo  	= null;
		UsuarioBean 	usuarioTO 	 	= null;
		UsuarioDAO 		usuarioDAO		= null;
		try{
			conectar();
			usuarioDAO	 	= new UsuarioDAO(conn);
			retUsuario		= new BResult();
			
			retUsuario = usuarioDAO.validaUsernamexPassword(username,password);
			// si el username y password estan registrados
			if(retUsuario.getCode()==0 && retUsuario.getObject()!=null){
				// si el numero de intentos es menor a 6
				if(((UsuarioBean)retUsuario.getObject()).getNumIntentos()<6){
					// si la cuenta esta activa
					if(((UsuarioBean)retUsuario.getObject()).getEstado().equalsIgnoreCase(ConstantesSECCD.ESTADO_ACTIVO)){
						usuarioTO = new UsuarioBean();
						usuarioTO = (UsuarioBean)retUsuario.getObject();
						moduloDAO 	 	= new ModuloDAO(conn);
						retModulo 		= new BResult();
						retModulo	= moduloDAO.obtieneModuloxPerfilUsuario(usuarioTO.getPerfil());
						if(retModulo.getCode()==0 && retModulo.getObject()!=null){
							listaModulo = (ArrayList<ModuloBean>)retModulo.getObject(); 
							perfilDAO		= new PerfilDAO(conn);
							retPerfil = new BResult();
							retPerfil = perfilDAO.getPerfil(usuarioTO.getCodigo());
							if(retPerfil.getCode()==0 && retPerfil.getObject()!=null){
								perfilTO		= new PerfilBean();
								perfilTO = (PerfilBean)retPerfil.getObject();
							}else{
								retSalida = new BResult();
								retSalida.setCode(-1);
								retSalida.setMessage("Error recuperando los modulos del perfil de usuario");
							}
							// resetea el numero de intentos fallidos
							usuarioDAO.reseteaNumIntentos(username);
							retSalida = new BResult();
							usuarioTO.setModulo(listaModulo);
							usuarioTO.setPerfilTO(perfilTO);
							retSalida.setObject(usuarioTO);
						}else{
							retSalida = new BResult();
							retSalida.setCode(-1);
							retSalida.setMessage(ConstantesSECCD.ERROR_BLOQUEO_CUENTA);
						}
					}else{ // si la cuenta esta inactiva
						retSalida = new BResult();
						retSalida.setMessage(ConstantesSECCD.ERROR_BLOQUEO_CUENTA);
						retSalida.setCode(-1);
					}
				}else{ // si el numero de intentos fallidos es mayor a 5
					// error por cantidad de intentos fallidos
					retSalida = new BResult();
					retSalida.setMessage(ConstantesSECCD.ERROR_BLOQUEO_CUENTA);
					retSalida.setCode(-1);
				}
			}else{ // si el usuario y password ingresados son incorrectos
				// se valida si el username esta registrado
				retUsuario = usuarioDAO.validaUsername(username);
				// si el username esta registrado
				if(retUsuario.getCode()==0){
					// registrar intento fallido
					int intentos = ((UsuarioBean)retUsuario.getObject()).getNumIntentos()+1;
					// se registra intentos fallidos para usuarios que no son administradores del sistema
					if(((UsuarioBean)retUsuario.getObject()).getPerfil()!=1){
						usuarioDAO.registraIntentoFallido(username,intentos);	
					}
					if(intentos==5){
						usuarioDAO.inactivaCuentaUsuario(username);
						retSalida = new BResult();
						retSalida.setCode(-1);
						retSalida.setMessage(ConstantesSECCD.ERROR_BLOQUEO_CUENTA);
					}else if(intentos>=5){
						retSalida = new BResult();
						retSalida.setCode(-1);
						retSalida.setMessage(ConstantesSECCD.ERROR_BLOQUEO_CUENTA);
					}
					else if(intentos<5){
						retSalida = new BResult();
						retSalida.setCode(-1);
						retSalida.setMessage(ConstantesSECCD.ERROR_CONTRASENA_INCORRECTA);
					}
				}else{
					// error por usuario no registrado
					retSalida = new BResult();
					retSalida.setCode(-1);
					retSalida.setMessage(ConstantesSECCD.ERROR_USER_NO_REGISTRADO);
				}
			}
		}catch(Exception e){
			retSalida = new BResult();
			retSalida.setCode(-1);
			retSalida.setMessage(ConstantesSECCD.ERROR_AMBIENTE);
		}finally{
			try{
				desconectar();
			}catch(Exception e){
				retSalida = new BResult();
				retSalida.setCode(-1);
				retSalida.setMessage("[UsuarioBO] error en metodo validaUsuario:"+e.getMessage());
			}
		}
		return retSalida;
	}
	
	public BResult cambiaClave(int codigoUsuario,String password) throws BusinessException{
		BResult 	ret	=	new BResult();
		try {
			conectar();
			UsuarioDAO 		usuarioDAO	 	= new UsuarioDAO(conn);
			ret = usuarioDAO.cambiaClave(codigoUsuario,password);
		} catch (Exception e) {
			ret.setCode(-1);
			ret.setMessage("[UsuarioBO] error en metodo cambiaClave:"+e.getMessage());
		}finally{
			try{
				desconectar();
			}catch(Exception e){
				ret = new BResult();
				ret.setCode(-1);
				ret.setMessage("[UsuarioBO]error en metodo cambiaClave:"+e.getMessage());
			}
		}
		return ret;
	}
	
	
	public BResult listarUsuario() throws BusinessException{
		BResult 				retSalida		= null;
		StringBuffer 			query 			= new StringBuffer(); 
		OperacionesComunesDAO	operacionesDAO	= null;
		try{
			conectar();
			operacionesDAO	 	= new OperacionesComunesDAO(conn);
			DynaBean dyna = Utilitario.seteaDynaBeanListadoTabla(null,null,null);
		    query = estableceQuery(dyna);
			retSalida 	= operacionesDAO.listado(query);
		}catch(Exception e){
			retSalida = new BResult();
			retSalida.setCode(-1);
			retSalida.setMessage("[UsuarioBO] error en metodo listarUsuario generado por:"+e.getMessage());
		}finally{
			try{
				desconectar();
			}catch(Exception e){
				retSalida = new BResult();
				retSalida.setCode(-1);
				retSalida.setMessage("[UsuarioBO] error en metodo listarUsuario generador po:"+e.getMessage());
			}
		}
		return retSalida;
	}
	
	public BResult buscarUsuario(DynaBean dyna) throws BusinessException{
		BResult 				retSalida		= null;
		OperacionesComunesDAO				operacionesDAO		= null;
		try{
			conectar();
			operacionesDAO	 	= new OperacionesComunesDAO(conn);
			StringBuffer query = estableceQuery(dyna);
			retSalida 	= operacionesDAO.listado(query);
		}catch(Exception e){
			retSalida = new BResult();
			retSalida.setCode(-1);
			retSalida.setMessage("[UsuarioBO] error en metodo buscarUsuario generado por:"+e.getMessage());
		}finally{
			try{
				desconectar();
			}catch(Exception e){
				retSalida = new BResult();
				retSalida.setCode(-1);
				retSalida.setMessage("[UsuarioBO] error en metodo buscarUsuario generador po:"+e.getMessage());
			}
		}
		return retSalida;
	}

	public BResult grabaEditaUsuario(DynaBean dyna) throws BusinessException{
		BResult 				retSalida		= null;
		UsuarioDAO				usuarioDAO		= null;
		try{
			conectar();
			usuarioDAO	 	= new UsuarioDAO(conn);
			retSalida 		= usuarioDAO.grabaEditaUsuario(dyna);
		}catch(Exception e){
			retSalida = new BResult();
			retSalida.setCode(-1);
			retSalida.setMessage("[UsuarioBO] error en metodo grabaEditaUsuario generado por:"+e.getMessage());
		}finally{
			try{
				desconectar();
			}catch(Exception e){
				retSalida = new BResult();
				retSalida.setCode(-1);
				retSalida.setMessage("[UsuarioBO] error en metodo grabaEditaUsuario generador po:"+e.getMessage());
			}
		}
		return retSalida;
	}
	
	public BResult grabaInsertaUsuario(DynaBean dyna) throws BusinessException{
		BResult 				retSalida		= null;
		UsuarioDAO				usuarioDAO		= null;
		try{
			conectar();
			usuarioDAO	 	= new UsuarioDAO(conn);
			int codigo		= usuarioDAO.obtieneUltimoCodigoUsuario();
			retSalida 		= usuarioDAO.grabaInsertaUsuario(dyna,codigo);
		}catch(Exception e){
			retSalida = new BResult();
			retSalida.setCode(-1);
			retSalida.setMessage("[UsuarioBO] error en metodo grabaInsertaUsuario generado por:"+e.getMessage());
		}finally{
			try{
				desconectar();
			}catch(Exception e){
				retSalida = new BResult();
				retSalida.setCode(-1);
				retSalida.setMessage("[UsuarioBO] error en metodo grabaInsertaUsuario generador po:"+e.getMessage());
			}
		}
		return retSalida;
	}
	
	public BResult buscarUsuarioEspecifico(DynaBean dyna) throws BusinessException{
		BResult 				retSalida		= null;
		UsuarioDAO				usuarioDAO		= null;
		try{
			conectar();
			usuarioDAO	 	= new UsuarioDAO(conn);
			retSalida 		= usuarioDAO.retornaUsuario(Utilitario.getPropertyDynaBean(dyna, "codigo"));
		}catch(Exception e){
			retSalida = new BResult();
			retSalida.setCode(-1);
			retSalida.setMessage("[UsuarioBO] error en metodo buscarUsuario generado por:"+e.getMessage());
		}finally{
			try{
				desconectar();
			}catch(Exception e){
				retSalida = new BResult();
				retSalida.setCode(-1);
				retSalida.setMessage("[UsuarioBO] error en metodo buscarUsuario generador po:"+e.getMessage());
			}
		}
		return retSalida;
	}

}
